package com.gzx.bi.modular.goals.monthly.service.impl;

import com.alibaba.fastjson2.JSON;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gzx.bi.modular.current.entity.GzxCurrentId;
import com.gzx.bi.modular.current.mapper.GzxCurrentIdMapper;
import com.gzx.bi.modular.goals.monthly.entity.GzxGoalsLineChartVo;
import com.gzx.bi.modular.goals.monthly.entity.GzxMonthlyGoals;
import com.gzx.bi.modular.goals.monthly.entity.bo.GzxMonthlyGoalsAddOrEditBo;
import com.gzx.bi.modular.goals.monthly.entity.bo.GzxMonthlyGoalsImportExcelBo;
import com.gzx.bi.modular.goals.monthly.entity.bo.GzxMonthlyGoalsQueryBo;
import com.gzx.bi.modular.goals.monthly.entity.bo.GzxMonthlyGoalsXxlEditBo;
import com.gzx.bi.modular.goals.monthly.entity.vo.GzxCommissionRatioListVo;
import com.gzx.bi.modular.goals.monthly.entity.vo.GzxMonthlyGoalsVo;
import com.gzx.bi.modular.goals.monthly.mapper.GzxMonthlyGoalsMapper;
import com.gzx.bi.modular.goals.monthly.service.GzxMonthlyGoalsService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.PostMapping;
import vip.xiaonuo.common.util.CommonDateUtil;
import vip.xiaonuo.common.util.MapstructUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

/**
 * @author zjt
 * @description
 * @date 2025/1/13 14:19
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class GzxMonthlyGoalsServiceImpl implements GzxMonthlyGoalsService {

    private final GzxMonthlyGoalsMapper monthlyGoalsMapper;

    private final GzxCurrentIdMapper currentIdMapper;

    private final GzxMonthlyGoalsMapper gzxMonthlyGoalsMapper;

    /**
     * 分页月度项目计划
     *
     * @param monthlyGoalsQueryBo
     * @return
     */
    @Override
    @DS("bi")
    public Page<GzxMonthlyGoalsVo> pageList(GzxMonthlyGoalsQueryBo monthlyGoalsQueryBo) {
        return monthlyGoalsMapper.selectVoPage(new Page<>(monthlyGoalsQueryBo.getCurrent(), monthlyGoalsQueryBo.getSize()), Wrappers.<GzxMonthlyGoals>lambdaQuery()
                .eq(StringUtils.isNotBlank(monthlyGoalsQueryBo.getProjectCode()), GzxMonthlyGoals::getProjectCode, monthlyGoalsQueryBo.getProjectCode())
                .eq(monthlyGoalsQueryBo.getBelongingMonth() != null, GzxMonthlyGoals::getBelongingMonth, monthlyGoalsQueryBo.getBelongingMonth())
                .orderByDesc(GzxMonthlyGoals::getId));
    }

    /**
     * 查询全部月度项目计划
     *
     * @param belongingMonth
     * @return
     */
    @Override
    @DS("bi")
    public List<GzxMonthlyGoalsVo> list(Integer belongingMonth) {
        return monthlyGoalsMapper.selectVoList(Wrappers.<GzxMonthlyGoals>lambdaQuery()
                .eq(GzxMonthlyGoals::getBelongingMonth, belongingMonth)
                .orderByDesc(GzxMonthlyGoals::getDeptId).orderByDesc(GzxMonthlyGoals::getProjectCode));
    }

    /**
     * 增加月度项目计划
     *
     * @param monthlyGoalsAddOrEditBo
     */
    @Override
    @DS("bi")
    public void add(GzxMonthlyGoalsAddOrEditBo monthlyGoalsAddOrEditBo) {
        monthlyGoalsMapper.insert(setMonthlyGoalsObj(monthlyGoalsAddOrEditBo));
    }

    /**
     * 修改月度项目计划
     *
     * @param monthlyGoalsAddOrEditBo
     */
    @Override
    @DS("bi")
    public void edit(GzxMonthlyGoalsAddOrEditBo monthlyGoalsAddOrEditBo) {
        monthlyGoalsMapper.updateById(setMonthlyGoalsObj(monthlyGoalsAddOrEditBo));
    }

    /**
     * 修改汇总金额
     *
     * @param monthlyGoalsXxlEditBo
     */
    @Override
    @DS("bi")
    public void modifyAchievementAmount(GzxMonthlyGoalsXxlEditBo monthlyGoalsXxlEditBo) {
        GzxMonthlyGoals monthlyGoals = getGzxMonthlyGoalsForTotal(monthlyGoalsXxlEditBo);
        if (monthlyGoals != null) {
            monthlyGoals.setMonthlyClientAmount(monthlyGoals.getMonthlyClientAmount().add(monthlyGoalsXxlEditBo.getMonthlyClientAmount()));
            if (StringUtils.isNotBlank(monthlyGoals.getDetailJson())) {
                monthlyGoals.setDetailJson(setDetailJson(monthlyGoals.getDetailJson(), monthlyGoalsXxlEditBo.getDayDetail()));
            }
            monthlyGoalsMapper.updateById(monthlyGoals);
        }
    }

    /**
     * 同步上月1号截止上月今天的累计达成金额
     *
     * @param monthlyGoalsXxlEditBo
     */
    @Override
    @DS("bi")
    public void modifyLastAmount(GzxMonthlyGoalsXxlEditBo monthlyGoalsXxlEditBo) {
        GzxMonthlyGoals monthlyGoals = getGzxMonthlyGoalsForTotal(monthlyGoalsXxlEditBo);
        if (monthlyGoals != null) {
            monthlyGoals.setLastMonthlyAchievementAmount(monthlyGoalsXxlEditBo.getLastMonthlyAchievementAmount());
            monthlyGoals.setLastMonthlyAdvancePayment(monthlyGoalsXxlEditBo.getLastMonthlyAdvancePayment());
            monthlyGoalsMapper.updateById(monthlyGoals);
        }
    }

    /**
     * 导入月度项目计划
     *
     * @param monthlyGoalsImportExcelBoList
     */
    @Override
    @DS("bi")
    public void importExcel(List<GzxMonthlyGoalsImportExcelBo> monthlyGoalsImportExcelBoList) {

    }

    /**
     * 获取折线图数据
     *
     * @param id
     * @return
     */
    @Override
    @DS("bi")
    public List<GzxGoalsLineChartVo> getChartData(Long id) {
        GzxMonthlyGoals monthlyGoals = monthlyGoalsMapper.selectById(id);
        Map<String, BigDecimal> monthlyGoalsMap = JSON.parseObject(monthlyGoals.getDetailJson(), TreeMap.class);
        List<GzxGoalsLineChartVo> goalsLineChartVoList = new ArrayList<>();
        for (Map.Entry<String, BigDecimal> entry : monthlyGoalsMap.entrySet()) {
            goalsLineChartVoList.add(new GzxGoalsLineChartVo(entry.getKey(), monthlyGoals.getMonthlyTargetAmount(), entry.getValue()));
        }
        return goalsLineChartVoList;
    }

    /**
     * 初始化本月的数据
     */
    @Override
    @DS("bi")
    public void initialize(Long id) {
        GzxCurrentId gzxCurrentId = currentIdMapper.selectById(1L);
        LambdaQueryWrapper<GzxCurrentId> wrapper = new LambdaQueryWrapper<>();
        gzxCurrentId.setCurrentId(id);
        currentIdMapper.update(gzxCurrentId, wrapper);
        String monthFirstDay = CommonDateUtil.getCurrentMonthFirstDay().replace("-", "").substring(0, 6);
        gzxMonthlyGoalsMapper.updateInit(monthFirstDay);
    }

    /**
     * 添加佣金比例明细
     *
     * @param json
     */
    @Override
    @DS("bi")
    @PostMapping("addRetaio")
    public void addRatio(String json, Long id) {
        GzxMonthlyGoals gzxMonthlyGoals = new GzxMonthlyGoals();
        gzxMonthlyGoals.setCommissionRatioList(json);
        gzxMonthlyGoals.setId(id);
        monthlyGoalsMapper.updateById(gzxMonthlyGoals);
    }

    @Override
    @DS("bi")
    public List<GzxCommissionRatioListVo> pageListRatio(GzxMonthlyGoalsAddOrEditBo monthlyGoalsAddOrEditBo) {
        Long id = monthlyGoalsAddOrEditBo.getId();
        GzxMonthlyGoals gzxMonthlyGoals = gzxMonthlyGoalsMapper.selectById(id);
        String list = gzxMonthlyGoals.getCommissionRatioList();
        if (StringUtils.isNotBlank(list)) {
            List<GzxCommissionRatioListVo> list1 = JSON.parseArray(list, GzxCommissionRatioListVo.class);
            return list1;
        }
        return null;
    }

    private GzxMonthlyGoals setMonthlyGoalsObj(GzxMonthlyGoalsAddOrEditBo monthlyGoalsAddOrEditBo) {
        GzxMonthlyGoals monthlyGoals = MapstructUtils.convert(monthlyGoalsAddOrEditBo, GzxMonthlyGoals.class);
        monthlyGoals.setCommission(null);
        monthlyGoals.setCommissionExclAdv(null);
        monthlyGoals.setCommissionAchievementRate(null);
        monthlyGoals.setMonRepayAr(null);
        monthlyGoals.setLastMonRepayAr(null);
        monthlyGoals.setMomDiff(null);
        //查询上月目标
        GzxMonthlyGoals lastMonthGoals = monthlyGoalsMapper.selectOne(Wrappers.<GzxMonthlyGoals>lambdaQuery()
                .eq(GzxMonthlyGoals::getDeptId, monthlyGoals.getDeptId())
                .eq(GzxMonthlyGoals::getProjectCode, monthlyGoals.getProjectCode())
                .eq(GzxMonthlyGoals::getBatchNumber, monthlyGoals.getBatchNumber())
                .eq(GzxMonthlyGoals::getBelongingMonth, CommonDateUtil.getLastMonth()));
        if (lastMonthGoals != null && lastMonthGoals.getMonthlyTargetAmount() != null) {
            monthlyGoals.setLastMonthlyTargetAmount(lastMonthGoals.getMonthlyTargetAmount());
        }
        return monthlyGoals;
    }

    private GzxMonthlyGoals getGzxMonthlyGoalsForTotal(GzxMonthlyGoalsXxlEditBo monthlyGoalsXxlEditBo) {
        GzxMonthlyGoals monthlyGoals = monthlyGoalsMapper.selectOne(Wrappers.<GzxMonthlyGoals>lambdaQuery()
                .eq(GzxMonthlyGoals::getProjectCode, monthlyGoalsXxlEditBo.getProjectCode())
                .eq(GzxMonthlyGoals::getBelongingMonth, CommonDateUtil.getCurrentMonth())
                .eq(GzxMonthlyGoals::getBatchNumber, monthlyGoalsXxlEditBo.getBatchNumber()));
        if (monthlyGoals == null) {
            log.error("发现新项目，但是未添加到项目计划中.........{}", monthlyGoalsXxlEditBo.getProjectCode());
            return null;
        }
        monthlyGoals.setMonthlyVarianceAmount(null);
        monthlyGoals.setCommission(null);
        monthlyGoals.setCommissionExclAdv(null);
        monthlyGoals.setCommissionAchievementRate(null);
        monthlyGoals.setMonRepayAr(null);
        monthlyGoals.setLastMonRepayAr(null);
        monthlyGoals.setMomDiff(null);
        return monthlyGoals;
    }

    private String setDetailJson(String detailJson, Map<String, BigDecimal> dayMap) {
        // 将 JSON 字符串解析为 Map，如果解析失败或为空，则初始化一个新的 HashMap
        Map<String, BigDecimal> dsMap = JSON.parseObject(detailJson, Map.class);
        if (dsMap == null) {
            dsMap = new TreeMap<>();
        }
        // 遍历新的 dayMap，将其值合并到 dsMap 中
        for (Map.Entry<String, BigDecimal> day : dayMap.entrySet()) {
            BigDecimal currentAmount = dsMap.getOrDefault(day.getKey(), BigDecimal.ZERO);
            dsMap.put(day.getKey(), currentAmount.add(day.getValue()));
        }
        return JSON.toJSONString(new TreeMap<>(dsMap));
    }
}
